from collections import OrderedDict
import time

from django.conf import settings
from django.contrib import messages
from django.db.models import Q, Sum
from django.http import JsonResponse
from django.shortcuts import render, redirect, reverse
from django_redis import get_redis_connection

from web import models
from web.utils.link import filter_reverse
from web.utils.pager import Pagernation
from web.utils.blackip import BlackIp


def attackip_list(request, pk):
    from django.contrib.messages.api import get_messages
    messages = get_messages(request)
    for msg in messages:
        print(msg)

    # 获取搜索条件
    search_list = [
        'attack_sip__contains',
        'location__contains'
    ]
    keyword = request.GET.get("keyword", "").strip()
    con = Q()
    con.connector = "OR"
    if keyword:
        for item in search_list:
            con.children.append((item, keyword))
    obj = models.SkyEye.objects.filter(id=pk).first()
    data_time = obj.create_datetime
    queryset = models.SkyEyeLog.objects.filter(con). \
        filter(create_datetime__year=data_time.year,
               create_datetime__month=data_time.month,
               create_datetime__day=data_time.day,
               ).exclude(attack_sip='').values('attack_sip', 'location').annotate(
        ct=Sum('repeat_count')).order_by('-ct')
    for row in queryset:
        association_devie_list = []
        botgate_exists = models.BotgateAttackIp.objects.filter(create_datetime__year=data_time.year,
                                                               create_datetime__month=data_time.month,
                                                               create_datetime__day=data_time.day,
                                                               src_ip=row['attack_sip']).exists()

        if botgate_exists:
            association_devie_list.append('BotGate')
        sangfor_exists = models.SangforFwAttackLog.objects.filter(create_datetime__year=data_time.year,
                                                                  create_datetime__month=data_time.month,
                                                                  create_datetime__day=data_time.day,
                                                                  src_ip=row['attack_sip']).exists()
        if sangfor_exists:
            association_devie_list.append('Sangfor_Fw')
        row['association_devie'] = ",".join(association_devie_list)
    pager = Pagernation(request, queryset)
    context = {
        'pager': pager,
        'keyword': keyword,
        'id': obj.id
    }
    return render(request, 'skyeye_attackip_list.html', context)


def block_ip(request, pk, src_ip):
    skyeye_obj = models.SkyEye.objects.filter(id=pk).first()
    date_time = skyeye_obj.create_datetime
    skyeye_attackip_obj = models.SkyEyeLog.objects.filter(create_datetime__year=date_time.year,
                                                          create_datetime__month=date_time.month,
                                                          create_datetime__day=date_time.day,
                                                          attack_sip=src_ip).first()
    if not skyeye_attackip_obj:
        messages.add_message(request, settings.MESSAGE_DANGER_TAG, 'IP不存在')
        return redirect(filter_reverse(request, reverse('skyeye_attackip_list', kwargs={'pk': pk})))

    # 将封禁IP写入redis
    block_ip = skyeye_attackip_obj.attack_sip
    location = skyeye_attackip_obj.location
    conn = get_redis_connection('default')
    user = request.session.get(settings.MOBILEDJ_SESSION_KEY)['id']
    blackip_obj = BlackIp(block_ip, 'sangfor_fw', settings.MANUAL_BLOCK, settings.BLOCK, user, date_time, location)
    conn.lpush(settings.QUEUE_TASK_NAME, str(blackip_obj))
    messages.add_message(request, messages.SUCCESS, '恶意IP：{}在深信服防火墙封禁成功'.format(block_ip))
    time.sleep(1)
    return redirect(filter_reverse(request, reverse('skyeye_attackip_list', kwargs={'pk': pk})))


def statistics_attackip(request):
    pk = request.GET.get('id')
    obj = models.SkyEye.objects.filter(id=pk).first()
    date_time = obj.create_datetime
    queryset = models.SkyEyeLog.objects.filter(create_datetime__year=date_time.year,
                                               create_datetime__month=date_time.month,
                                               create_datetime__day=date_time.day). \
        values('attack_sip').annotate(ct=Sum('repeat_count')).order_by("-ct")
    all_attackip_dict = OrderedDict()
    for item in queryset:
        all_attackip_dict[item['attack_sip']] = {
            'name': item['attack_sip'],
            'level': {item[0]: 0 for item in models.SkyEyeLog.hazard_level_choices}
        }
    attack_log = models.SkyEyeLog.objects.filter(create_datetime__year=date_time.year,
                                                 create_datetime__month=date_time.month,
                                                 create_datetime__day=date_time.day)

    for item in attack_log:
        all_attackip_dict[item.attack_sip]['level'][item.hazard_level] += item.repeat_count

    categories = [data['name'] for data in all_attackip_dict.values()]

    data_result_dict = OrderedDict()
    for item in models.SkyEyeLog.hazard_level_choices:
        data_result_dict[item[0]] = {'name': item[1], "data": []}
    for key, text in models.SkyEyeLog.hazard_level_choices:
        for row in all_attackip_dict.values():
            count = row['level'][key]
            data_result_dict[key]['data'].append(count)
    context = {
        'status': True,
        'data': {
            'categories': categories,
            'series': list(data_result_dict.values())
        }
    }

    return JsonResponse(context)
